const jwt = require('jsonwebtoken');
const User = require('../models/User');
const JWTKET = process.env.JWT_KEY
const { sendResponse, sendListResponse } = require('../utils/response');
const { getTimestamp, getTwoDigits, formatTime } = require('../utils/common');
const UserProfile = require('../models/UserProfile');
const moment = require('moment');
const checkinController = require('./checkinController');
const sequelize = require('../db/db');
const { Op } = require('sequelize');


// 用于存储黑名单的 Token
const tokenBlacklist = new Set();

// 注册
exports.registerUser = async (req, res) => {
  const { userName, password, roleType } = req.body;
  try {
    const user = await User.findOne({ where: { user_name: userName, role_type: roleType } })
    if (user) {
      sendResponse(res, 400, "该账号已存在")
      return; // 终止函数执行
    }
    const userId = "181" + getTimestamp() + getTwoDigits()
    const str = userId.slice(-4)
    const nickname = roleType == '0' ? '管理员' + str : "用户" + str
    const currentTime = formatTime(new Date());

    // 使用事务确保用户创建和用户资料创建的原子性
    const transaction = await sequelize.transaction();

    try {
      // 创建用户
      await User.create({
        user_id: userId,
        user_name: userName,
        password,
        role_type: roleType,
        nickname,
        create_time: currentTime
      }, { transaction });

      // 只有普通用户(roleType=1)才创建UserProfile
      if (roleType == '1') {
        const profileId = "191" + getTimestamp() + getTwoDigits();
        await UserProfile.create({
          id: profileId,
          user_id: userId,
          total_question: 0,
          total_score: 0,
          correct_rate: 0.00,
          battle_win: 0
        }, { transaction });
      }

      // 提交事务
      await transaction.commit();
      sendResponse(res, 200, "注册成功");
    } catch (error) {
      // 回滚事务
      await transaction.rollback();
      console.error("注册事务错误:", error);
      throw error; // 抛出错误以便被外层catch捕获
    }
  } catch (error) {
    console.log("注册err", error);
    sendResponse(res, 500, "注册失败: " + error.message)
  }
};

// 登录
exports.loginUser = async (req, res) => {
  const { userName, password, roleType } = req.body;
  try {
    const user = await User.findOne({ where: { user_name: userName, role_type: roleType } });
    if (!user || user.password !== password) {
      sendResponse(res, 400, "密码错误或者用户不存在")
      return;
    }

    // 更新最后登录时间
    await user.update({
      last_login: formatTime(new Date())
    });

    // 生成 JWT
    const token = jwt.sign(
      {
        userId: user.user_id,
        userName: user.user_name,
        roleType: user.role_type
      },
      JWTKET,
      { expiresIn: '24h' }
    );

    // 返回用户信息和token
    const info = {
      userId: user.user_id,
      userName: user.user_name,
      roleType: user.role_type,
      nickname: user.nickname,
      sex: user.sex,
      createTime: user.create_time,
      lastLogin: user.last_login,
    }
    sendResponse(res, 200, "登录成功", { token, info })
  } catch (error) {
    console.log(error);
    sendResponse(res, 500, "登录失败")
  }
};

// 登出
exports.logoutUser = (req, res) => {
  const token = req.header('Authorization'); // 从请求头中获取 Token

  if (!token) {
    sendResponse(res, 400, "No token provided")
    return;
  }

  // 将 Token 加入黑名单
  tokenBlacklist.add(token);

  sendResponse(res, 200, "登出成功")
};

// 验证 Token 的中间件
exports.verifyToken = (req, res, next) => {
  const token = req.header('Authorization');

  if (!token) {
    sendResponse(res, 401, "No token provided")
    return;
  }
  // 检查 Token 是否在黑名单中
  if (tokenBlacklist.has(token)) {
    sendResponse(res, 401, "令牌无效。请重新登录")
    return;
  }

  try {
    // 验证 Token
    const decoded = jwt.verify(token.trim(), JWTKET);
    req.user = decoded; // 将解码后的用户信息附加到 req 对象中
    next();
  } catch (err) {
    if (err.name === 'TokenExpiredError') {
      sendResponse(res, 401, '令牌已过期')
      return;
    } else {
      sendResponse(res, 401, '令牌无效。请重新登录')
      return;
    }
  }
};

// 获取用户byID
exports.getUserById = async (req, res) => {
  const userId = req.params.id;
  try {
    const user = await User.findByPk(userId);
    if (!user) {
      sendResponse(res, 400, "User not found")
    } else {
      const info = {
        userId: user.user_id,
        userName: user.user_name,
        roleType: user.role_type,
        nickname: user.nickname,
        sex: user.sex,
        createTime: user.create_time,
        lastLogin: user.last_login,
      }
      sendResponse(res, 200, "获取成功", info)
    }
  } catch (error) {
    console.log(error);
    sendResponse(res, 500, 'Failed to get user')
  }
};

// 验证token并重新生成 Token
exports.checkToken = async (req, res) => {
  try {
    // 从 req.user 中获取用户信息
    const user = req.user;

    if (!user) {
      return sendResponse(res, 400, 'User information not found');
    }
    const userRes = await User.findByPk(user.userId)
    const { user_id, user_name, role_type, nickname, password, sex, create_time, last_login } = userRes.dataValues
    // 生成新 Token
    const newToken = jwt.sign({ userId: user_id, userName: user_name, roleType: role_type }, JWTKET, { expiresIn: '24h' });

    // 返回新 Token 和用户信息
    const info = {
      userId: user_id,
      userName: user_name,
      roleType: role_type,
      nickname,
      sex,
      createTime: create_time,
      lastLogin: last_login,
    }
    sendResponse(res, 200, '登录成功', {
      token: newToken,
      info,
    });
  } catch (err) {
    console.error('Error in checkToken:', err);
    sendResponse(res, 500, 'Internal server error');
  }
};

// 修改用户信息
exports.updateUserInfo = async (req, res) => {
  const updateData = req.body; // 获取要更新的字段

  try {
    const { id } = updateData
    // 查找用户
    const user = await User.findByPk(id);
    if (!user) {
      return sendResponse(res, 404, "用户不存在");
    }
    let params = {
      ...updateData,
    }
    delete params["id"]
    // 更新字段
    await user.update(params);

    const { user_id, user_name, role_type, nickname, password, sex, create_time, last_login } = user.dataValues;
    const userInfo = {
      userId: user_id,
      userName: user_name,
      roleType: role_type,
      nickname,
      password,
      sex,
      createTime: create_time,
      lastLogin: last_login,
    }
    sendResponse(res, 200, "用户信息更新成功", userInfo);
  } catch (error) {
    console.error("更新用户信息失败:", error);
    sendResponse(res, 500, "更新用户信息失败");
  }
};

// 获取用户列表，支持分页
exports.getUserList = async (req, res) => {
  try {
    // 获取分页参数
    const { page = 1, pageSize = 10, roleType, keyword = '' } = req.query;

    // 构建查询条件
    const whereCondition = {};
    // 先处理roleType条件
    if (roleType !== undefined && roleType !== '') {
      whereCondition.role_type = roleType.toString();
    }
    // 再处理关键词搜索
    if (keyword) {
      whereCondition[Op.or] = [
        { user_name: { [Op.like]: `%${keyword}%` } },
        { nickname: { [Op.like]: `%${keyword}%` } }
      ];
    }

    // 计算偏移量
    const offset = (parseInt(page) - 1) * parseInt(pageSize);

    // 查询用户总数
    const total = await User.count({ where: whereCondition });

    // 查询用户列表
    const users = await User.findAll({
      where: whereCondition,
      attributes: ['user_id', 'user_name', 'role_type', 'nickname', 'sex', 'create_time', 'last_login'],
      order: [['create_time', 'DESC']],
      limit: parseInt(pageSize),
      offset: offset
    });

    // 格式化用户数据
    const formattedUsers = users.map(user => ({
      userId: user.user_id,
      userName: user.user_name,
      roleType: user.role_type,
      nickname: user.nickname,
      sex: user.sex,
      createTime: user.create_time,
      lastLogin: user.last_login
    }));

    // 返回分页数据
    sendListResponse(res, 200, "获取用户列表成功", formattedUsers, total);
  } catch (error) {
    console.error('获取用户列表失败:', error);
    sendResponse(res, 500, '获取用户列表失败', error.message);
  }
};

module.exports;